﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PSE.Tools.SchemaComparer.Extractor;

namespace PSE.Tools.SchemaComparer.Comparer
{
    public abstract class DBObjectComparer<TObject>
        where TObject : DBObject
    {
        public List<DBObjectCompareResult> Compare(DBObjectList<TObject> sourceObjects, DBObjectList<TObject> targetObjects)
        {
            List<DBObjectCompareResult> result = new List<DBObjectCompareResult>();

            //equanto houver itens na lista de tabelas do Schema Source
            while (sourceObjects.Count > 0)
            {
                //recuperar a primeira tabela do Schema Source
                TObject sourceObject = sourceObjects[0];
                sourceObjects.RemoveAt(0);

                if (targetObjects.Contains(sourceObject.Name))
                {
                    //procurar a tabela no Schema Target
                    TObject targetObject = targetObjects[sourceObject.Name];

                    targetObjects.Remove(targetObject);

                    DBObjectCompareResult cr = Compare(sourceObject, targetObject);
                    if (cr != null)
                    {
                        cr.ObjectType = GetObjectType();
                        result.Add(cr);
                    }
                }
                else
                {
                    //se não encontrar, remover a tabela do Schema Source, e adicionar um resultado a lista indicando que a tabela existe apenas no Schema Source
                    DBObjectCompareResult cr = new DBObjectCompareResult();
                    cr.ObjectName = sourceObject.Name;
                    cr.ObjectType = GetObjectType();
                    cr.CompareStatus = DBObjectCompareStatus.ObjectExistOnlyInSourceSchema;
                    result.Add(cr);
                }
            }

            //varrer a lista de tabelas existentes apenas no target, e adicionar um resultado a lista indicando que o objeto existe apenas no Schema Target
            foreach (TObject targetObject in targetObjects)
            {
                DBObjectCompareResult cr = new DBObjectCompareResult();
                cr.ObjectName = targetObject.Name;
                cr.ObjectType = GetObjectType();
                cr.CompareStatus = DBObjectCompareStatus.ObjectExistOnlyInTargetSchema;
                result.Add(cr);
            }

            return result;
        }

        protected virtual string GetObjectType()
        {
            Type t = typeof(TObject);
            return t.Name;
        }

        protected abstract DBObjectCompareResult Compare(TObject sourceObject, TObject targetObject);
    }
}
